﻿using System;
using NthDownload.Contracts;
using System.ComponentModel.Composition;

namespace NthDownload.Navigation
{
    [PartCreationPolicy(CreationPolicy.Shared)]
    [InheritedExport(typeof(INavigationService))]
    public class NavigationService : INavigationService
    {
        #region Events

        #region ShowRequested

        /// <summary>
        /// Is raised when the show method is called
        /// </summary>
        public event EventHandler<NavigationRequestedEventArgs> ShowRequested;

        protected void OnShowRequested(IViewModel viewModel, Action<IViewModel> showCallback)
        {
            if (ShowRequested != null)
            {
                ShowRequested.Invoke(this, new NavigationRequestedEventArgs(viewModel, showCallback, false));
            }
        }

        #endregion ShowRequested

        #region ShowDialogRequested

        /// <summary>
        /// Is raised when the ShowDialog method is called
        /// </summary>
        public event EventHandler<NavigationRequestedEventArgs> ShowDialogRequested;

        protected void OnShowDialogRequested(IViewModel viewModel, Action<IViewModel> showCallback, bool fullscreen)
        {
            if (ShowDialogRequested != null)
            {
                ShowDialogRequested.Invoke(this, new NavigationRequestedEventArgs(viewModel, showCallback, fullscreen));
            }
        }

        #endregion ShowDialogRequested

        #endregion Events

        #region Methods

        /// <summary>
        /// Requests a view be shown for a view model.
        /// </summary>
        /// <param name="viewModel">The view model for which to show the view.</param>
        /// <param name="shownCallback">The delegate which in invoked after the entire process is complete.</param>
        public void Show(IViewModel viewModel, Action<IViewModel> shownCallback)
        {
            //
            // Raise show requested
            //
            OnShowRequested(viewModel, shownCallback);
        }

        /// <summary>
        /// Requests a view be shown for a view model.
        /// </summary>
        /// <param name="viewModel">The view model for which to show the view.</param>
        public void Show(IViewModel viewModel)
        {
            Show(viewModel, null);
        }

        /// <summary>
        /// Requests a view be shown for a view model in a dialog popup.
        /// </summary>
        /// <param name="viewModel">The view model for which to show the view.</param>
        /// <param name="shownCallback">The delegate which in invoked after the entire process is complete.</param>
        /// <param name="fullscreen">Indicates if the dialogc should be shown fullscreen.</param>
        public ViewModelResults ShowDialog(IViewModel viewModel, Action<IViewModel> shownCallback, bool fullscreen)
        {
            //
            // Raise show requested
            //
            OnShowDialogRequested(viewModel, shownCallback, fullscreen);

            //
            // Return dialog result
            //
            return viewModel.Result;
        }

        /// <summary>
        /// Requests a view be shown for a view model in a dialog popup.
        /// </summary>
        /// <param name="viewModel">The view model for which to show the view.</param>
        /// <param name="fullscreen">Indicates if the dialogc should be shown fullscreen.</param>
        public ViewModelResults ShowDialog(IViewModel viewModel, bool fullscreen)
        {
            return ShowDialog(viewModel, null, fullscreen);
        }

        #endregion Methods
    }
}
